// eslint-disable-next-line @typescript-eslint/no-namespace
namespace a {
  interface Animal {
    swings: string;
    fly: any;
  }

  //如果装饰器函数是用来修饰类的话 那么target就是类的构造函数本身
  // function flyable(target: any) {
  //   console.log(target)
  //
  //   target.prototype.swings = 2
  //   target.prototype.fly = function () {
  //     console.log('I can fly')
  //   }
  // }

  //装饰器工厂↓
  function flyable(swing: any) {
    return function flyable(target: any){
      console.log(target)

      target.prototype.swings = 2
      target.prototype.fly = function () {
        console.log('I can fly')
      }
    }
  }

  // @flyable
  @flyable(5)
  class Animal {
    constructor() {
      //
    }
  }
  const animal: Animal = new Animal()
  console.log(animal.swings)
  animal.fly()
}

// eslint-disable-next-line @typescript-eslint/no-namespace
namespace b{
  interface Person {
    protoName: string;
  }

  //实例属性的时候target是类的原型对象, key是属性的名字
  function instancePropertyDecorator(target: any, key: any){
    target.protoName = '我是类的原型上的属性'
    console.log('instancePropertyDecorator:', target, key)
  }

  //类的静态属性时候 target就是类的构造函数 key就是属性名
  function classPropertyDecorator(target: any, key: any) {
    console.log('classPropertyDecorator:')
  }

  //如果是实例的方法的话 target是类的原型 key方法名 descriptor属性描述符
  function instanceMethodDecorator(target: any, key: any, descriptor: any) {
    console.log('instanceMethodDecorator:', target, key, descriptor)
  }

  //如果是类的方法的话target是类的构造函数 key方法名 descriptor属性描述符
  function classMethodDecorator(target: any, key: any, descriptor: any){
    console.log('classMethodDecorator:', target, key, descriptor)
  }

  class Person {
    @instancePropertyDecorator
    //@ts-ignore
    instanceProperty: string; //实例属性
    @classPropertyDecorator
    static classProperty: string //类的景甜属性
    @instanceMethodDecorator
    instanceMethod() { //实例的亭台方法

    }
    @classMethodDecorator
    static classMethod(){ // 类的静态方法

    }
  }

  console.log(new Person())
}
